#ifndef __MYSTRING__
#define __MYSTRING__
//3个特殊函数:拷贝构造函数、拷贝赋值函数和析构函数
//对于不带有指针的类,这3个函数可以使用编译器默认为我们生成的版本;但是编写带有指针的类时就有必要定义这3个特殊函数.
//构造函数和析构函数中执行数据的深拷贝和释放.
#include <cstring>
#include <iostream>

class String
{
public:
    String(const char* cstr = 0);
    String(const String& str);
    String& operator=(const String& str);
    ~String();
    char* get_c_str() const 
    {
        return m_data;
    }
private:
    char* m_data;
};
//构造函数
inline String::String(const char* cstr)
{
    std::cout << "String::String" << std::endl;
    if (cstr) {
        m_data = new char[strlen(cstr) + 1];
        strcpy(m_data, cstr);
    }
    else {
        m_data = new char[1];
        *m_data = '\0';
    }
}
//析构函数
inline String::~String()
{
    std::cout << "String :: ~String" << std::endl;
    delete[] m_data;
    //值得注意的是使用delete[]操作符释放数组内存,若直接使用delete操作符释放数组内存虽然能够通过编译,但有可能产生内存泄漏.
}

//拷贝构造函数的实现较为简单,直接调用友元对象的数据指针进行拷贝即可.
inline String::String(const String& str)
{
    std::cout << "------copy Sstring----" << std::endl;
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
}
//拷贝赋值函数
inline String& String::operator=(const String& str)
{
    std::cout << "---------asign =====" << std::endl;
    if (this == &str)
        return *this;     //检测是否自我赋值
    //1清空内存
    delete[] m_data;
    //2.重新申请内存
    m_data = new char[strlen(str.m_data) + 1];
    //3.拷贝内容到新申请的内存
    strcpy(m_data, str.m_data);
    return *this;
}

#include <iostream>
std::ostream& operator<<(std::ostream& os, const String& str)
{
    os << str.get_c_str();
    return os;
}

#endif